home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 13
/
Aminet 13 - August 1996.iso
/
Aminet
/
mus
/
misc
/
ChordianV1_0.lha
/
Chordian.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-06-10
|
6KB
|
257 lines
/*********************************************************************************
** Chordian -- a program to mix tunes of a sample into a chord **
** **
** Released to the public domain by Andreas Fredriksson (dep@canit.se) **
** **
** If you use this program or the source code in any way, mention my name. **
** **
*********************************************************************************/
#include <stdio.h>
#include <math.h>
float diffs[]={ 1.0000, 1.0594, 1.1225, 1.1892,
1.2600, 1.3348, 1.4142, 1.4983,
1.5874, 1.6818, 1.7817, 1.8878 };
char infoline[]={"Chordian v1.0 -- copyright (c)1996 by Andreas Fredriksson (dep@canit.se)\n"};
char usage[]={"
Usage:\n
Chordian <sample> <output> [i] n1 n2 [n3..]\n
<sample> the sample you wish to make a chord from
<output> the chord sample to create
i use interpolation
the n values are tones relative to the basenote
values n1,n2 are required but up to 4 may be given\n
example:
Chordian organ.raw organchord i 0 3 7\n
This would create a minor chord from the sample 'organ.raw' and
place the result in the file 'organchord'.\n\n"};
long filesize(FILE *f)
{
long s;
fseek(f,0,2); s=ftell(f); rewind(f);
return(s);
}
/* cut(): not needed anymore but kept if I want to change the smp-size someday */
/*
void cut(float *f,long s)
{
if(*f>=s) *f=s-1;
}
*/
/* macro to get the fractional part from a float */
#define frac(a) (a-floor(a))
int main(int argc, char *argv[])
{
FILE *in,*out;
int x;
long csize,size=0;
char interpolate=0, num, *sample, *chord;
char numnotes=-1, notes[4]={0,0,0,0}, *tmp;
float pos1=0,pos2=0,pos3=0,pos4=0,tmpfloat,v1,v2,v3,v4;
float step1=0,step2=0,step3=0,step4=0;
if(argc<5) { printf("%s%s",infoline,usage); exit(0); }
printf("%s",infoline);
/* open files needed */
if(!(in=fopen(argv[1],"rb"))) { printf("Couldn't open file '%s'.\n",argv[1]); exit(0); }
if(!(out=fopen(argv[2],"wb"))) { printf("Couldn't create file '%s'.\n",argv[2]); fclose(in); exit(0);}
/* check for 'i' flag */
if(*argv[3]=='i' || *argv[3]=='I')
{
interpolate=1;
num=4;
puts("Interpolation enabled.");
}
else num=3;
/* read the notes */
tmp=notes; /* set up a pointer */
while(num<=argc && numnotes<4)
{
*tmp++=atoi(argv[num]);
numnotes++;
num++;
}
/* print some info */
printf("Mixing sample '%s' to '%s'.\n",argv[1],argv[2]);
printf("Notes in use (%d) :",numnotes);
for(x=0;x<numnotes;x++)
{
printf(" %d",notes[x]);
}
printf("\n");
/* allocate memory and read the sample */
size=filesize(in);
sample=(char *)malloc(size);
chord=(char *)malloc(size);
if( (!(sample)) || (!(chord)) )
{
fclose(in); fclose(out);
puts("Error: Out of memory.");
exit(0);
}
fread(sample,1,size,in);
/* do the mixing */
step1=diffs[notes[0]]; /* get stepvalues */
step2=diffs[notes[1]];
step3=diffs[notes[2]];
step4=diffs[notes[3]];
/* find biggest stepvalue, divide size with it to get chord size */
tmpfloat=-10;
if(step1>tmpfloat) tmpfloat=step1;
if(step2>tmpfloat) tmpfloat=step2;
if(step3>tmpfloat) tmpfloat=step3;
if(step4>tmpfloat) tmpfloat=step4;
csize=size/tmpfloat;
printf("Sample size: %d\n",size);
printf(" Chord size: %d (based on highest note)\n",csize);
tmp=chord; /* set up a pointer */
if(interpolate)
{
switch(numnotes)
{
case 2:
for(x=0;x<size;x++)
{
v1=sample[(int)pos1]*(1-frac(pos1))+
+sample[(int)pos1+1]*(frac(pos1));
v2=sample[(int)pos2]*(1-frac(pos2))+
+sample[(int)pos2+1]*(frac(pos2));
*tmp++=(v1+v2)/2;
pos1+=step1;
pos2+=step2;
}
break;
case 3:
for(x=0;x<size;x++)
{
v1=sample[(int)pos1]*(1-frac(pos1))+
+sample[(int)pos1+1]*(frac(pos1));
v2=sample[(int)pos2]*(1-frac(pos2))+
+sample[(int)pos2+1]*(frac(pos2));
v3=sample[(int)pos3]*(1-frac(pos3))+
+sample[(int)pos3+1]*(frac(pos3));
*tmp++=(v1+v2+v3)/3;
pos1+=step1;
pos2+=step2;
pos3+=step3;
}
break;
case 4:
for(x=0;x<size;x++)
{
v1=sample[(int)pos1]*(1-frac(pos1))+
+sample[(int)pos1+1]*(frac(pos1));
v2=sample[(int)pos2]*(1-frac(pos2))+
+sample[(int)pos2+1]*(frac(pos2));
v3=sample[(int)pos3]*(1-frac(pos3))+
+sample[(int)pos3+1]*(frac(pos3));
v4=sample[(int)pos4]*(1-frac(pos4))+
+sample[(int)pos4+1]*(frac(pos4));
*tmp++=(v1+v2+v3+v4)/4;
pos1+=step1;
pos2+=step2;
pos3+=step3;
pos4+=step4;
}
break;
}
}
else
{
switch(numnotes)
{
case 2:
for(x=0;x<csize;x++)
{
/*cut(&pos1,size); cut(&pos2,size);*/
*tmp++= (sample[(int)pos1]
+sample[(int)pos2])/2;
pos1+=step1;
pos2+=step2;
}
break;
case 3:
for(x=0;x<csize;x++)
{
/*cut(&pos1,size); cut(&pos2,size); cut(&pos3,size);*/
*tmp++= (sample[(int)pos1]
+sample[(int)pos2]
+sample[(int)pos3])/3;
pos1+=step1;
pos2+=step2;
pos3+=step3;
}
break;
case 4:
for(x=0;x<csize;x++)
{
/*cut(&pos1,size); cut(&pos2,size); cut(&pos3,size); cut(&pos4,size);*/
*tmp++= (sample[(int)pos1]
+sample[(int)pos2]
+sample[(int)pos3]
+sample[(int)pos4])/4;
pos1+=step1;
pos2+=step2;
pos3+=step3;
pos4+=step4;
}
break;
}
}
/* save data to disk */
printf("Saving data.. ");
fwrite(chord,1,csize,out);
printf("done.\n");
/* close files & free memory */
free(sample);
free(chord);
fclose(in);
fclose(out);
}